/**
 * Copyright (c) 2012 Fujian FUNO Mobile Communication Technology Co., Ltd.
 * All rights reserved by FUNO.
 */
package com.funo.util;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.logging.Log;

/**
 * 日志工具类
 * 
 * <hr/>
 * <b>2012-5-24:</b> 新建
 * <hr/>
 * 
 * @author linzhiwei
 * 
 * @version V1.0
 */
public class LogUtils {

	/**
	 * 
	 * @param log
	 * @param pattern
	 * @param params
	 */
	public static void debug(Log log, String pattern, Object... params) {
		if (null == log || !log.isDebugEnabled() || StringUtils.isBlank(pattern)) {
			return;
		}
		log.debug(addMethodCallInfo(handleMsg(pattern, params)));
	}
	
	public static void trace(Log log, String pattern, Object... params) {
		if (null == log || !log.isDebugEnabled() || StringUtils.isBlank(pattern)) {
			return;
		}
		log.trace(addMethodCallInfo(handleMsg(pattern, params)));
	}

	public static void info(Log log, String pattern, Object... params) {
		if (null == log || !log.isInfoEnabled() || StringUtils.isBlank(pattern)) {
			return;
		}
		log.info(addMethodCallInfo(handleMsg(pattern, params)));
	}

	public static void warn(Log log, String pattern, Object... params) {
		if (null == log || !log.isWarnEnabled() || StringUtils.isBlank(pattern)) {
			return;
		}
		log.warn(addMethodCallInfo(handleMsg(pattern, params)));
	}
	
	public static void error(Log log, String pattern, Object... params) {
		if (null == log || !log.isErrorEnabled() || StringUtils.isBlank(pattern)) {
			return;
		}
		log.error(handleMsg(pattern, params));
	}

	private static String addMethodCallInfo(String message){
		StackTraceElement[] elements = Thread.currentThread().getStackTrace();
		if(null != elements && elements.length > 2){
			return elements[3].toString() + message;
		}
		return message;
	}
	
	public static String handleMsg(String pattern, Object... params) {
		return handleMsg2(pattern, params);
	}

	/**
	 * 先按{}分组,在拼接
	 * 
	 * @param pattern
	 * @param params
	 * @return
	 */
	@SuppressWarnings("unused")
	@Deprecated
	private static String handleMsg1(String pattern, Object[] params) {

		if (null == params || params.length == 0) {
			return pattern;
		}
		String[] strs = StringUtils.split(" " + pattern, "{}");
		StringBuilder sb = new StringBuilder(pattern.length());
		int len = strs.length < params.length ? strs.length : params.length;
		for (int i = 0; i < len; i++) {
			sb.append(strs[i]).append(params[i]);
		}
		for (int i = len; i < strs.length; i++) {
			sb.append(strs[i]);
		}
		return sb.toString();
	}

	/**
	 * 直接替换{}
	 * 
	 * @param pattern
	 * @param params
	 * @return
	 */
	private static String handleMsg2(String pattern, Object[] params) {

		if (null == params || params.length == 0) {
			return pattern;
		}
		for (int i = 0; i < params.length; i++) {
			if(null == params[i]){
				continue;
			}
			pattern = StringUtils.replaceOnce(pattern, "{}", handleType(params[i]));
		}

		return pattern;
	}

	private static String handleType(Object o) {
        if(null == o){
        	return "";
        }
        if(o instanceof Number || o instanceof String || o instanceof Iterable<?> ){
        	return o.toString();
        }
		if (o.getClass().isArray()) {
			StringBuilder sb = new StringBuilder("{");
			Object[] target = (Object[]) o;
			for (Object element : target ) {
				if(null == element){
					sb.append("null").append(",");
				}else{
					sb.append(element.toString()).append(",");
				}
				
			}
			sb.setCharAt(sb.length() - 1, '}');
			return sb.toString();
		}
		return ToStringBuilder.reflectionToString(o);
	}

}
